package com.zhajh.socket;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import com.zhajh.utils.Const;
import com.zhajh.utils.PackData;

public class ClientHandler extends IoHandlerAdapter
{
    public interface MsgCallback
    {
        public void procRecvData(IoBuffer buf);
    }

    private int mAckFuncId = 0;
    private IoBuffer mAckBuffer = null;
    private MsgCallback mMsgCallback = null;

	public ClientHandler(Map<Long, IoSession> managedSessions) {
		System.out.println("客户器启动");
	}

	/*
	 * 当接口中其他方法抛出异常未被捕获时触发此方法
	 */
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		System.out.println("当接口中其他方法抛出异常未被捕获时触发:" + cause.getMessage());
	}

	/*
	 * 当信息已经传送给服务端后触发此方法.
	 */
	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		System.out.println("当信息已经传送给服务端后触发:"+session.getRemoteAddress());
	}

	/*
	 * 当一个新服务端连接后触发此方法.
	 */
	@Override
	public void sessionCreated(IoSession session) throws Exception {
		System.out.println("当一个新服务端连接后触发:"+session.getRemoteAddress());
	}

	/*
	 * 当连接空闲时触发此方法.
	 */
	@Override
	public void sessionIdle(IoSession session, IdleStatus status)
			throws Exception {
		System.out.println("当连接空闲时触发:"+session.getRemoteAddress());
	}

	/*
	 * 当连接后打开时触发此方法，一般此方法与 sessionCreated 会被同时触发
	 */
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		System.out.println("服务端上线:" + session.getRemoteAddress());
	}

	/*
	 * 当连接被关闭时触发，例如服务端程序意外退出等等.
	 */
	@Override
	public void sessionClosed(IoSession session) throws Exception {

		CloseFuture closeFuture = session.close(true);
		closeFuture.addListener(new IoFutureListener<IoFuture>() {
			public void operationComplete(IoFuture future) {
				if (future instanceof CloseFuture) {
					((CloseFuture) future).setClosed();
					System.out.println("服务端下线:"
							+ future.getSession().getRemoteAddress());
				}
			}
		});
	}

	public void setAckFuncId(int id)
	{
	    mAckFuncId = id;
	    mAckBuffer = null;
	}

	public IoBuffer getAck()
	{
		synchronized (this)
		{
			final IoBuffer buf = mAckBuffer;
			return buf;
		}
	}

	public void setAck(IoBuffer buf)
	{
		synchronized (this)
		{
			mAckBuffer = buf;
		}
	}

	/*
	 * 当接收到服务端的请求信息后触发此方法
	 */
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		//String datetime = sdf.format(new Date());
		//System.out.println("收到服务端数据("+session.getRemoteAddress()+")：" + datetime);
		PackData msg = (PackData) message;
		//DataEncyt encyt = new DataEncyt();
		IoBuffer ib = msg.getIoBuffer();
		procRecvData(ib);
	}

	private void procRecvData(IoBuffer buf)
	{
	    int funcId = buf.getInt();
        buf.rewind();

		if (funcId == mAckFuncId)
		{
			setAck(buf);
			return;
		}

		if (mMsgCallback != null)
		{
		    mMsgCallback.procRecvData(buf);
		}
	}

	public void setMsgCallback(ClientHandler.MsgCallback cb)
    {
        mMsgCallback = cb;
    }
}
